#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <string.h>
#include <sys/types.h>

#define __USE_XOPEN2K 1
#include <unistd.h>

#define strequ(a, b) (strcmp(a, b) == 0)

static ssize_t match_str(const char *target, const char *str) {
        size_t tl = strlen(target);
        size_t sl = strlen(str);
        if (tl > sl) {
                return -1;
        } else if (tl == sl) {
                return strequ(target, str)?
                    0:
                    -1;
        } else {
                for (size_t i = 0 ; i < tl ; i ++) {
                        if (target[i] != *(str++))
                                return -1;
                }
                return (ssize_t)(sl - tl);
        }
}

#ifndef _NO_TEST_NAME
#define mat(a) do {                             \
        ssize_t g = match_str("pacman", a);     \
        if (g != -1)                            \
                return g;                       \
        if (*(++a) == '\0')                     \
                return -1;                      \
} while (0)
static ssize_t is_pacman(const char *name) {
        // It is not fast, but work.
        mat(name);
        mat(name);
        mat(name);
        return -1;
}
#endif // !_NO_TEST_NAME

#define emat(target, str) if (match_str(target, str) != -1) return true;
static bool fine_action(const char *opt) {
        emat("-S", opt);
#ifdef _ALLOW_OPT_U
        // Allow user to install file maybe dangerous
        emat("-U", opt);
#endif //_ALLOW_OPT_U
        emat("-D", opt);
        return false;
}

int main(int ac, char **av) {
        (void)ac;
#ifndef _NO_TEST_NAME
        ssize_t pg = is_pacman(basename(av[0]));
        if (pg == -1 || pg > 2) {
                fprintf(stderr, "Only use for pacman!\n");
                exit(1);
        }
#endif // !_NO_TEST_NAME
        if (geteuid() != 0) {
                fprintf(stderr, "EUID not root!\n");
                goto exec;
        }
        if (ac >= 2 && fine_action(av[1])) {
                // Root
                if (setuid(0) == -1) {
                        fprintf(stderr, "UID set error.\n");
                }
        } else {
                // User
                uid_t uu = getuid();
                if (seteuid(uu) == -1) {
                        perror("Command not trust, but can't drop the EUID");
                        fprintf(stderr, "Try `/usr/bin/pacman` instead.\n");
                        exit(1);
                }
        }
exec:
        av[0] = "/usr/bin/pacman";
        execvp(av[0], av);
        perror("Command run fail");
        exit(1);
}
